package org.jaronsource.framework.core.service;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;

import org.jaronsource.framework.core.dao.support.Criteria;
import org.jaronsource.framework.core.dao.support.IEntity;
import org.jaronsource.framework.core.dao.support.Page;
import org.jaronsource.framework.core.dao.support.PageRequest;
import org.jaronsource.framework.core.dao.support.Sort;
import org.springframework.transaction.annotation.Transactional;

@Transactional
public abstract class GenericService<T extends IEntity<I>, I extends Serializable> implements IGenericService<T, I> {

	@Override
	public T save( T target ) {
		return getDao().save( target );
	}

	@Override
	public T[] save( T... targets ) {
		for ( T target : targets ) {
			save( target );
		}
		return targets;
	}
	
	@Override
	public void update( T target, I pk ) {
		getDao().update( target, pk );
	}

	@Override
	public void remove( I id ) {
		getDao().remove( id );
	}
	
	@Override
	public void remove( I... ids ) {
		for ( I id : ids ) {
			remove( id );
		}
	}

	@Override
	@Transactional ( readOnly = true)
	public boolean exists( I id ) {
		return getDao().exists( id );
	}

	@Override
	@Transactional ( readOnly = true)
	public T findReferenceByPk( I id ) {
		return getDao().findReferenceByPk( id );
	}

	@Override
	@Transactional ( readOnly = true)
	public T findByPk( I id ) {
		return getDao().findByPk( id );
	}

	@Override
	@Transactional ( readOnly = true)
	public T findOne( Criteria criteria ) {
		return getDao().findOne( criteria );
	}

	@Override
	@Transactional ( readOnly = true)
	public T findOne( Sort sort, Criteria criteria ) {
		return getDao().findOne( sort, criteria );
	}

	@Override
	@Transactional ( readOnly = true)
	public T findOne( String jpql, Object... params ) {
		return getDao().findOne( jpql, params );
	}

	@Override
	@Transactional ( readOnly = true)
	public T findOne( String jpql, Map<String, ?> params ) {
		return getDao().findOne( jpql, params );
	}

	@Override
	@Transactional ( readOnly = true)
	public T findOne( Sort sort, String jpql, Object... params ) {
		return getDao().findOne( sort, jpql, params );
	}

	@Override
	@Transactional ( readOnly = true)
	public T findOne( Sort sort, String jpql, Map<String, ?> params ) {
		return getDao().findOne( sort, jpql, params );
	}

	@Override
	@Transactional ( readOnly = true)
	public List<T> find( Criteria criteria ) {
		return getDao().find( criteria );
	}

	@Override
	@Transactional ( readOnly = true)
	public List<T> find( String jpql, Object... params ) {
		return getDao().find( jpql, params );
	}

	@Override
	@Transactional ( readOnly = true)
	public List<T> find( PageRequest pageRequest, Criteria criteria ) {
		return getDao().find( pageRequest, criteria );
	}

	@Override
	@Transactional ( readOnly = true)
	public List<T> find( PageRequest pageRequest, String jpql, Object... params ) {
		return getDao().find( pageRequest, jpql, params );
	}

	@Override
	@Transactional ( readOnly = true)
	public long count( Criteria criteria ) {
		return getDao().count( criteria );
	}

	@Override
	@Transactional ( readOnly = true)
	public long count( String jpql, Object... params ) {
		return getDao().count( jpql, params );
	}

	@Override
	@Transactional ( readOnly = true)
	public Page<T> findPage( PageRequest pageRequest, Criteria criteria ) {
		return getDao().findPage( pageRequest, criteria );
	}

	@Override
	@Transactional ( readOnly = true)
	public Page<T> findPage(	PageRequest pageRequest,
								String jpql,
								Object... params ) {
		return getDao().findPage( pageRequest, jpql, params );
	}

	protected EntityManager getEntityManager() {
		return getDao().getEntityManager();
	}

	@Override
	@Transactional ( readOnly = true)
	public List<T> find( String jpql, Map<String, ?> params ) {
		return getDao().find( jpql, params );
	}

	@Override
	@Transactional ( readOnly = true)
	public List<T> find(	PageRequest pageRequest,
							String jpql,
							Map<String, ?> params ) {
		return getDao().find( pageRequest, jpql, params );
	}

	@Override
	@Transactional ( readOnly = true)
	public long count( String jpql, Map<String, ?> params ) {
		return getDao().count( jpql, params );
	}

	@Override
	@Transactional ( readOnly = true)
	public Page<T> findPage(	PageRequest pageRequest,
								String jpql,
								Map<String, ?> params ) {
		return getDao().findPage( pageRequest, jpql, params );
	}

	@Override
	@Transactional ( readOnly = true)
	public List<T> find( Sort sort, Criteria criteria ) {
		return getDao().find( sort, criteria );
	}

	@Override
	@Transactional ( readOnly = true)
	public List<T> find( Sort sort, String jpql, Object... params ) {
		return getDao().find( sort, jpql, params );
	}

	@Override
	@Transactional ( readOnly = true)
	public List<T> find( Sort sort, String jpql, Map<String, ?> params ) {
		return getDao().find( sort, jpql, params );
	}

	@Override
	@Transactional ( readOnly = true)
	public List<T> findAll() {
		return getDao().findAll();
	}

}
